In dieser Lerneinheit geht es um das Thema SQL-Injections. Das sind Sicherheitslücken bei der Arbeit mit Datenbanken. Und wir schauen uns an, wie man sich mit Prepared Statements wirksam davor schützen kann. Eine SQL-Injection bezeichnet das Ausnutzen einer Sicherheitslücke in Zusammenhang mit SQL-Datenbanken, die durch mangelnde Maskierung oder Überprüfung von Metazeichen in Benutzereingaben entsteht. SQL-Injections sind dann möglich, wenn Daten wie beispielsweise Benutzereingaben in den SQL-Interpreter gelangen. Denn Benutzereingaben können Zeichen enthalten, die für den SQL-Interpreter Sonderfunktion besitzen und so Einfluss von außen auf die ausgeführten Datenbankbefehle ermöglichen. Solche Metazeichen in SQL sind zum Beispiel der Backslash, das Anführungszeichen, der Apostroph und das Semikolon. Der Angreifer versucht dabei, über die Anwendung, die den Zugriff auf die Datenbank bereitstellt, eigene Datenbankbefehle einzuschleusen. Sein Ziel ist es, Daten auszuspähen, Daten in seinem Sinne zu verändern, die Kontrolle über den Server zu erhalten oder einfach größtmöglichen Schaden anzurichten. Das Bild erklärt, wie eine SQL-Injection entsteht und warum sie ein ernsthaftes Sicherheitsrisiko darstellt. Es vergleicht einen regulären, unkritischen Datenbankzugriff mit einem manipulierten Angriffsszenario. Im ersten Fall wird eine Benutzeranfrage korrekt verarbeitet. Die Anwendung erhält eine einfache Eingabe, etwa eine ID-Nummer, die in eine Datenbankabfrage eingebunden wird. Dadurch wird gezielt ein bestimmter Datensatz aus der Datenbank abgerufen, etwa ein Artikel mit einer bestimmten Nummer. Die erzeugte Datenbankabfrage ist eindeutig und bleibt auf die vorgesehene Funktion beschränkt. Im zweiten Fall wird jedoch eine gefährliche Situation demonstriert. Statt einer einfachen ID gibt ein Angreifer eine manipulierte Zeichenkette ein, die nicht nur eine reguläre ID enthält, sondern zusätzlich eine schädliche Datenbankanweisung. Die Webanwendung erkennt diesen Unterschied nicht, weil sie die Eingabe ungeprüft direkt in die Abfrage einsetzt. Dadurch wird neben dem regulären Datenbankzugriff auch eine zusätzliche, vom Angreifer gewünschte Aktion ausgeführt – zum Beispiel das Ändern von Benutzerrechten oder das Löschen von Daten. Diese Art von Angriff funktioniert, weil die Anwendung die Benutzereingabe nicht ausreichend prüft oder absichert. Der Datenbankserver verarbeitet alle enthaltenen Befehle nacheinander – auch solche, die nie vorgesehen waren. Das kann zu schweren Sicherheitsproblemen führen, wie dem unbefugten Zugriff auf sensible Daten oder der Übernahme von Benutzerkonten. Das gezeigte Beispiel verdeutlicht, wie wichtig es ist, Eingaben von außen niemals direkt in Datenbankabfragen zu übernehmen. Das Bild zeigt, wie eine Suchfunktion durch eine SQL-Injection missbraucht werden kann. Im Normalfall wird ein eingegebenes Stichwort in der Datenbank gesucht, etwa um passende Titel oder URLs anzuzeigen. Wird das Suchwort jedoch manipuliert und bösartiger Code eingefügt, kann der Angreifer die Datenbank dazu bringen, zusätzliche gefährliche Befehle auszuführen – in diesem Fall sogar einen Befehl zum Herunterfahren des Servers. Die Ursache liegt darin, dass die Eingabe ungeprüft in die SQL-Abfrage übernommen wird. Das Bild zeigt erneut ein Beispiel für eine SQL-Injection, diesmal mit dem Ziel, vertrauliche Daten wie Logins und Passwörter auszulesen. Im normalen Fall wird über eine ID ein bestimmter Artikel aus der Datenbank abgefragt. Durch eine manipulierte Eingabe kann jedoch eine zweite Abfrage angehängt werden, die Inhalte aus einer ganz anderen Tabelle – etwa der Benutzertabelle – ausliest. So können sensible Informationen ungewollt offengelegt werden. Diese Technik nutzt den sogenannten Union-Befehl aus SQL, der mehrere Ergebnismengen kombiniert. Wenn der Code etwa so aufgebaut ist, dass ein Statement direkt aus einer Eingabe zusammengesetzt wird, kann ein Angreifer leicht eigene Befehle einschleusen. Genau das ist die Schwachstelle, auf die SQL-Injection-Angriffe abzielen. Um solche Schwachstellen zu vermeiden, gibt es Prepared Statements. Ein Prepared Statement ist eine sogenannte vorbereitete Anweisung für ein Datenbanksystem. Im Gegensatz zu gewöhnlichen Statements enthält es noch keine Parameterwerte. Stattdessen werden dem Datenbanksystem Platzhalter übergeben. Mittels Prepared Statements können SQL-Injections effektiv verhindert werden, da das Datenbanksystem die Gültigkeit von Parametern prüft, bevor diese verarbeitet werden. Soll ein Statement mit unterschiedlichen Parametern mehrere Male (zum Beispiel innerhalb einer Schleife) auf dem Datenbanksystem ausgeführt werden, können Prepared Statements zusätzlich einen Geschwindigkeitsvorteil bringen, da das Statement schon vor-übersetzt im Datenbanksystem vorliegt und nur noch mit den neuen Parametern ausgeführt werden muss. Wenn ein Programm externe Eingaben direkt in einen SQL-String integriert – etwa durch Stringverkettung, öffnet es Tür und Tor für Manipulationen. Ein Angreifer könnte diese Schnittstelle nutzen, um eigene SQL-Befehle einzuschleusen. Im Gegensatz dazu zeigt diese Folie die empfohlene und sichere Lösung durch die Nutzung von Prepared Statements. Die Platzhalter werden nicht einfach durch String-Verkettung ersetzt. Stattdessen verwenden sie eine sichere Schnittstelle des Datenbanktreibers. Dieser stellt sicher, dass die eingefügten Werte nicht als SQL-Befehle interpretiert werden können – selbst wenn sie Sonderzeichen enthalten.